#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "spf.h"




int spf_encode_init(spf_t* spf, int len)
{
	char* buffer = (char*) malloc(sizeof(char) * len);
	if (buffer == NULL) {
		return -1;
	}
	memset(buffer, 0, len);
	spf->payload = buffer;
	spf->len = len;
	spf->ptr = 0;
	return 0;
}


void spf_encode_deinit(spf_t* spf)
{
	free(spf->payload);
	spf->len = 0;
	return;
}


int spf_encode_add_int(spf_t* spf, char* key, int value)
{

	char buffer[12] = { 0 };
	itoa(value, buffer, 10);

	int key_len = strlen(key);
	int value_len = strlen(buffer);
	int total_len = spf->ptr + key_len + value_len + 2;
	if (total_len >= spf->len) {
		printf("payload available space is not enough\n");
		return -1;
	}
	strcat(spf->payload, key);
	spf->payload[spf->ptr + key_len] = CFG_KV_SEPARATOR;
	strcat(spf->payload, buffer);
	spf->payload[total_len - 1] = CFG_TERMINATOR;
	spf->ptr = total_len;
	return 0;

}

int spf_encode_add_string(spf_t* spf, char* key, char* value)
{
	int key_len = strlen(key);
	int value_len = strlen(value);
	int total_len = spf->ptr + key_len + value_len + 2;
	if (total_len >= spf->len) {
		printf("payload available space is not enough\n");
		return -1;
	}
	strcat(spf->payload, key);
	spf->payload[spf->ptr + key_len] = CFG_KV_SEPARATOR;
	strcat(spf->payload, value);
	spf->payload[total_len - 1] = CFG_TERMINATOR;
	spf->ptr = total_len;
	return 0;
}



int spf_encode_add_float(spf_t* spf, char* key, float value)
{

	char* buffer[16] = { 0 };
	sprintf(buffer, "%f", value);

	int key_len = strlen(key);
	int value_len = strlen(buffer);
	int total_len = spf->ptr + key_len + value_len + 2;
	if (total_len >= spf->len) {
		printf("payload available space is not enough\n");
		return -1;
	}
	strcat(spf->payload, key);
	spf->payload[spf->ptr + key_len] = CFG_KV_SEPARATOR;
	strcat(spf->payload, buffer);
	spf->payload[total_len - 1] = CFG_TERMINATOR;
	spf->ptr = total_len;
	return 0;
}




int spf_decode_init(spf_t* format, char* payload, int len)
{
	char* buffer = (char*) malloc(sizeof(char) * len);
	if (buffer == NULL) {
		return -1;
	}
	memcpy(buffer, payload, len);
	format->payload = buffer;
	format->len = len;
	format->ptr = 0;
	return 0;
}


int spf_decode_get_int(spf_t* spf, char* key, int* value)
{
	char* payload = spf->payload;
	int key_len = strlen(key);
	int key_index = 0;

	for (int i = 0; i < spf->len - key_len; i++) {   // only march the buffer length before spf->len - key_len
		if (payload[i] == key[0]) {
			int march_time = 0;
			for (int j = 0; j < key_len; j++) {
				if (payload[i + j] != key[j]) {
					break;
				}
				march_time++;
			}
			if (march_time == key_len) {
				i = i + key_len;
				if (payload[i] != CFG_KV_SEPARATOR) {
					return -1;
				}
				char buffer[12] = { 0 };
				int j = 0;
				for (i = i + 1; i < spf->len; i++) {
					if (payload[i] == CFG_TERMINATOR || j >= 12) {
						break;
					}
					buffer[j++] = payload[i];
				}
				int v = atoi(buffer);
				*value = v;
				return 0;
			}
		}
	}
	return -1;
}



int spf_decode_get_float(spf_t* spf, char* key, float* value)
{
	char* payload = spf->payload;
	int key_len = strlen(key);
	int key_index = 0;

	for (int i = 0; i < spf->len - key_len; i++) {   // only march the buffer length before spf->len - key_len
		if (payload[i] == key[0]) {
			int march_time = 0;
			for (int j = 0; j < key_len; j++) {
				if (payload[i + j] != key[j]) {
					break;
				}
				march_time++;
			}
			if (march_time == key_len) {
				i = i + key_len;
				if (payload[i] != CFG_KV_SEPARATOR) {
					return -1;
				}
				char buffer[16] = { 0 };
				int j = 0;
				for (i = i + 1; i < spf->len; i++) {
					if (payload[i] == CFG_TERMINATOR || j >= 12) {
						break;
					}
					buffer[j++] = payload[i];
				}
				float v = atof(buffer);
				*value = v;
				return 0;
			}
		}
	}
	return -1;
}


int spf_decode_get_string(spf_t* spf, char* key, char* value, int len)
{
	char* payload = spf->payload;
	int key_len = strlen(key);
	int key_index = 0;

	for (int i = 0; i < spf->len - key_len; i++) {  // only march the buffer length before spf->len - key_len
		if (payload[i] == key[0]) {
			int march_time = 0;
			for (int j = 0; j < key_len; j++) {
				if (payload[i + j] != key[j]) {
					break;
				}
				march_time++;
			}
			if (march_time == key_len) {
				i = i + key_len;
				if (payload[i] != CFG_KV_SEPARATOR) {
					return -1;
				}
				int j = 0;
				for (i = i + 1; i < spf->len; i++) {
					if (payload[i] == CFG_TERMINATOR) {
						break;
					}
					if (j >= len) {
						return -2;
					}
					value[j++] = payload[i];
				}
				return 0;
			}
		}
	}
	return -1;
}